import re, datetime, time, pdb
from math import cos, sin, pi
import math
from mozi_ai_sdk.btmodel.bt import utils
from mozi_simu_sdk.geo import get_horizontal_distance, get_end_point
from mozi_simu_sdk.mssnpatrol import CPatrolMission
from mozi_simu_sdk.mssnstrike import CStrikeMission
from mozi_simu_sdk.args import Throttle
from mozi_ai_sdk.test.bt_test import bt_etc_antiship as etc
from mozi_simu_sdk.doctrine import CDoctrine
from mozi_simu_sdk.contact import CContact

lst = ['闪电 #9', '闪电 #10', '闪电 #11', '闪电 #12', '闪电 #13', '闪电 #14', '闪电 #15', '闪电 #16']

AD_Time = 39 * 60
A_lon = 1.24
D_lon = 0.26
strike_StartTime = '     '
T = 40 * 60
AttackTime2 = 55 * 60
AttackTime3 = 65 * 60


def evade_ship(geopoint_target, air, mission_doctrine):  # 躲避驱逐舰接口，实际效果不佳
    geopoint_air = (air.dLatitude, air.dLongitude)
    if geopoint_target:
        dis = get_horizontal_distance(geopoint_air, geopoint_target)
        if dis <= 75:
            mission_doctrine.ignore_plotted_course('yes')
            genpoint_away = get_end_point(geopoint_air, 1.6, (air.fCurrentHeading + 30))
            air.plot_course([genpoint_away])


def create_antisurfaceship_mission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    contacts = side.contacts
    airs_dic = side.aircrafts
    # 获取反舰任务飞机
    airs_1 = {k: v for k, v in airs_dic.items() if int(re.sub('\D', '', v.strName)) < 5}
    airs_2 = {k: v for k, v in airs_dic.items() if
              (int(re.sub('\D', '', v.strName)) > 5 and int(re.sub('\D', '', v.strName)) < 9)}
    if len(contacts) == 0 or len(airs_1) == 0:
        return False
    target_1 = {k: v for k, v in contacts.items() if ('DDG' in v.strName)}
    mssnSitu = side.strikemssns
    if {k: v for k, v in mssnSitu.items() if v.strName == 'strike1'}.__len__() == 0:
        side.add_mission_strike('strike1', 2)
        strkmssn_1 = CStrikeMission('T+1_mode', scenario.mozi_server, scenario.situation)
        strkmssn_1.strName = 'strike1'
        strkmssn_1.m_Side = side_name
        strkmssn_1.side_name = side_name
        # 取消满足编队规模才能起飞的限制（任务条令）
        strkmssn_1.set_start_time(strike_StartTime)
        strkmssn_1.set_flight_size(4)
        strkmssn_1.set_flight_size_check(side_name, 'strike1', 'False')
        # strkmssn_1.set_auto_planner(True) #多扇面攻击
        strkmssn_1.mozi_server.send_and_recv(
            "ScenEdit_SetDoctrineWRA({side='%s',WEAPON_ID='826', target_type= '3104'},{qty_salvo='max',shooter_salvo='max',firing_range='inherit',self_defence='max'})" % side_name)
        side.add_mission_strike('strike2', 2)
    else:
        return False
    strkmssn_1.assign_targets(target_1)
    strkmssn_1.assign_units(airs_1)
    return False

def update_antisurfaceship_mission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    airs_dic = side.aircrafts
    airsOnMssn = {k: v for k, v in airs_dic.items() if v.strActiveUnitStatus.find('正在执行任务') > 0}
    airs = {k: v for k, v in airs_dic.items() if int(re.sub('\D', '', v.strName)) < 9}
    contacts = side.contacts
    if airsOnMssn.__len__() == 0:
        return False
    if len(contacts) == 0 or len(airs) == 0:
        return False

    mssnSitu = side.strikemssns
    strkmssn = [v for v in mssnSitu.values() if 'strike' in v.strName]
    if len(strkmssn) != 1:
        return False
    return False

def update_patrol_mission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    # 从敌方所有单元中取到目标
    targets = side.contacts
    target = [v for k, v in targets.items() if '阿里伯克' in v.strName]
    geopoint_target = None
    if target:
        geopoint_target = (target[0].dLatitude, target[0].dLongitude)

    airs_dic = side.aircrafts

    # 执行任务的飞机,
    airs = {k: v for k, v in airs_dic.items() if int(re.sub('\D', '', v.strName)) >= 9}

    # 获取巡逻任务，如果巡逻任务为0，说明还没有，创建巡逻任务
    patrol_missions_dic = side.get_patrol_missions()
    patrol_missions = [mission for mission in patrol_missions_dic.values()]
    if len(patrol_missions) == 0:
        return False


    i = 0
    try:
        for patrol_mission in patrol_missions:
            if patrol_mission.strName == 'defensive_xl1':
                airs_xl1 = {k: airs[k] for k, v in airs.items() if v.strName in lst[2:5]}
                patrol_mission.assign_units(airs_xl1)
                patrol_mission.add_prosecution_zone(['ju0', 'ju1', 'ju2', 'ju3', 'ju4', 'ju5', 'ju6',
                                                     'ju7', 'ju8', 'ju9', 'ju10', 'ju11'])
                doctrine_xl1 = patrol_mission.get_doctrine()
                patrol_mission.set_flight_size(1)
                patrol_mission.switch_radar(False)
                patrol_mission.set_emcon_usage(True)
                patrol_mission.mozi_server.send_and_recv(
                    "ScenEdit_SetMission('%s', 'defensive_xl1',{oneThirdRule=true,FlightSize='1',useFlightSize=false,"
                    "starttime='2020年4月16日22:04:55'})" % side_name)

            if patrol_mission.strName == 'defensive_xl2':
                airs_xl4 = {k: airs[k] for k, v in airs.items() if v.strName in lst[5:8]}
                patrol_mission.assign_units(airs_xl4)
                patrol_mission.add_prosecution_zone(
                    ['jd0', 'jd1', 'jd2', 'jd3', 'jd4', 'jd5', 'jd6', 'jd7', 'jd8', 'jd9', 'jd10', 'jd11'])
                doctrine_xl4 = patrol_mission.get_doctrine()
                patrol_mission.set_flight_size(1)
                patrol_mission.set_emcon_usage(True)
                patrol_mission.switch_radar(False)
                patrol_mission.mozi_server.send_and_recv(
                    "ScenEdit_SetMission('%s', 'defensive_xl2',{oneThirdRule=true,FlightSize='1',useFlightSize=false,"
                    "starttime='2020年4月16日22:06:00'})" % side_name)
            if patrol_mission.strName == 'defensive_xl3':
                airs_xl3 = {k: airs[k] for k, v in airs.items() if v.strName in lst[:2]}
                patrol_mission.assign_units(airs_xl3)
                patrol_mission.set_emcon_usage(True)
                patrol_mission.switch_radar(False)
                patrol_mission.add_prosecution_zone(
                    ['jj0', 'jj1', 'jj2', 'jj3', 'jj4', 'jj5', 'jj6', 'jj7', 'jj8', 'jj9', 'jj10', 'jj11'])
                patrol_mission.mozi_server.send_and_recv(
                    "ScenEdit_SetMission('%s', 'defensive_xl3',{oneThirdRule=true,FlightSize='1',useFlightSize=false,starttime='2020年4月16日22:20:01'})" % side_name)
            i += 1
    except Exception as e:
        print(e)
    update_patrol_zone(side_name, scenario)
    update_guard_zone(side_name, scenario)

    return False


def create_patrol_mission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    airs_dic = side.aircrafts
    patrol_missions_dic = side.get_patrol_missions()
    # 任务创建判断
    if len(patrol_missions_dic) != 0:
        for k in patrol_missions_dic:
            if 'defensive_xl' in patrol_missions_dic[k].strName:
                return False
    airs_c = [v for v in airs_dic.values() if 4 < int(re.sub('\D', '', v.strName)) < 9]  # 编号5，6,7,8的,4架飞机
    # patrol_missions_dic = side.get_patrol_missions()
    patrol_mission_name = [mission.strName for mission in patrol_missions_dic.values()]
    # 根据驱逐舰的坐标，确定巡逻区参考点，根据巡逻区参考点，创建巡逻区
    point_list = create_patrol_zone(side_name, scenario)
    create_guard_zone(side_name, scenario)
    i = 1
    for point in point_list:
        point_str = []
        for name in point:
            point_str.append(name.strName)
        # 新建巡逻区名字
        patrol_name = 'defensive_xl' + str(i)
        side.add_mission_patrol(patrol_name, 0, point_str)
        patrolmssn = CPatrolMission('T+1_mode', scenario.mozi_server, scenario.situation)
        patrolmssn.strName = patrol_name
        patrolmssn.set_one_third_rule(side_name, 'true')
        i += 1
    return False

def create_patrol_zone(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    ships = side.ships
    point_list = []
    # 根据本方航空母舰的位置创建巡逻区xl1，xl2
    if side_name == '红方':
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon += A_lon
                else:
                    lon += D_lon
                # xl1
                rp1 = side.add_reference_point('rp1', lat + 1.2, lon + 0)
                rp2 = side.add_reference_point('rp2', lat + 1, lon + 0.5)
                rp3 = side.add_reference_point('rp3', lat + 0.6, lon + 0)
                rp4 = side.add_reference_point('rp4', lat + 1, lon - 0.5)
                point_list.append([rp1, rp2, rp3, rp4])
                # xl2
                rp5 = side.add_reference_point('rp5', lat - 0.7, lon + 0)
                rp6 = side.add_reference_point('rp6', lat - 1, lon + 0.5)
                rp7 = side.add_reference_point('rp7', lat - 1.2, lon + 0)
                rp8 = side.add_reference_point('rp8', lat - 1, lon - 0.5)
                point_list.append([rp5, rp6, rp7, rp8])
                # xl3
                rp13 = side.add_reference_point('rp13', lat + 0.25, lon - 1)
                rp14 = side.add_reference_point('rp14', lat + 0.25, lon - 0.3)
                rp15 = side.add_reference_point('rp15', lat - 0.25, lon - 0.3)
                rp16 = side.add_reference_point('rp16', lat - 0.25, lon - 1)
                point_list.append([rp13, rp14, rp15, rp16])
    else:
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon -= A_lon
                else:
                    lon -= D_lon
                # xl1
                rp1 = side.add_reference_point('rp1', lat + 1.2, lon + 0)
                rp2 = side.add_reference_point('rp2', lat + 1, lon + 0.5)
                rp3 = side.add_reference_point('rp3', lat + 0.6, lon + 0)
                rp4 = side.add_reference_point('rp4', lat + 1, lon - 0.5)
                point_list.append([rp1, rp2, rp3, rp4])
                # xl2
                rp5 = side.add_reference_point('rp5', lat - 0.7, lon - 0)
                rp6 = side.add_reference_point('rp6', lat - 1, lon - 0.5)
                rp7 = side.add_reference_point('rp7', lat - 1.2, lon - 0)
                rp8 = side.add_reference_point('rp8', lat - 1, lon + 0.5)
                point_list.append([rp5, rp6, rp7, rp8])
                # xl3
                rp13 = side.add_reference_point('rp13', lat + 0.25, lon + 1)
                rp14 = side.add_reference_point('rp14', lat + 0.25, lon + 0.3)
                rp15 = side.add_reference_point('rp15', lat - 0.25, lon + 0.3)
                rp16 = side.add_reference_point('rp16', lat - 0.25, lon + 1)
                point_list.append([rp13, rp14, rp15, rp16])
    return point_list


def update_patrol_zone(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    ships = side.ships
    ref_points = {}
    refpnts = side.referencepnts
    for k, v in refpnts.items():
        ref_points[v.strName] = k

    if side_name == '红方':
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon += A_lon
                else:
                    lon += D_lon
                # xl1
                side.set_reference_point('rp1', lat + 1.2, lon + 0)
                side.set_reference_point('rp2', lat + 1, lon + 0.5)
                side.set_reference_point('rp3', lat + 0.6, lon + 0)
                side.set_reference_point('rp4', lat + 1, lon - 0.5)
                # xl2
                side.set_reference_point('rp5', lat - 0.7, lon + 0)
                side.set_reference_point('rp6', lat - 1, lon + 0.5)
                side.set_reference_point('rp7', lat - 1.2, lon + 0)
                side.set_reference_point('rp8', lat - 1, lon - 0.5)

                # xl3
                side.set_reference_point('rp13', lat + 0.25, lon - 1)
                side.set_reference_point('rp14', lat + 0.25, lon - 0.3)
                side.set_reference_point('rp15', lat - 0.25, lon - 0.3)
                side.set_reference_point('rp16', lat - 0.25, lon - 1)
    else:
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon -= A_lon
                else:
                    lon -= D_lon
                # xl1
                side.set_reference_point('rp1', lat + 1.2, lon - 0)
                side.set_reference_point('rp2', lat + 1, lon - 0.5)
                side.set_reference_point('rp3', lat + 0.6, lon - 0)
                side.set_reference_point('rp4', lat + 1, lon + 0.5)
                # xl2
                side.set_reference_point('rp5', lat - 0.7, lon - 0)
                side.set_reference_point('rp6', lat - 1, lon - 0.5)
                side.set_reference_point('rp7', lat - 1.2, lon - 0)
                side.set_reference_point('rp8', lat - 1, lon + 0.5)

                # xl3
                side.set_reference_point('rp13', lat + 0.25, lon + 1)
                side.set_reference_point('rp14', lat + 0.25, lon + 0.3)
                side.set_reference_point('rp15', lat - 0.25, lon + 0.3)
                side.set_reference_point('rp16', lat - 0.25, lon + 1)


def create_guard_zone(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    ships = side.ships
    ref_points = {}
    refpnts = side.referencepnts
    for k, v in refpnts.items():
        ref_points[v.strName] = k
 
    if side_name == '红方':
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon += A_lon
                else:
                    lon += D_lon
            # xl1
    else:
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon -= A_lon
                else:
                    lon -= D_lon
    for theta in range(0, 13, 1):
        side.add_reference_point('jj' + str(theta), lat + 1.8 * sin(theta * pi / 6),
                                 lon + 1.8 * cos(theta * pi / 6))
        side.add_reference_point('ju' + str(theta), lat + 0.6 + 1.8 * sin(theta * pi / 6),
                                 lon + 0.3 + 1.8 * cos(theta * pi / 6))
        side.add_reference_point('jd' + str(theta), lat - 0.6 + 1.8 * sin(theta * pi / 6),
                                 lon + 0.3 + 1.8 * cos(theta * pi / 6))


def update_guard_zone(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    ships = side.ships
    ref_points = {}
    refpnts = side.referencepnts
    for k, v in refpnts.items():
        ref_points[v.strName] = k
    # 根据本方驱逐舰的位置创建警戒区xl1，xl2
    if side_name == '红方':
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon += A_lon
                else:
                    lon += D_lon
            # xl1
    else:
        for k, v in ships.items():
            # lat: 纬度， lon：经度
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                if get_current_time(scenario) > AD_Time:
                    lon -= A_lon
                else:
                    lon -= D_lon
    for theta in range(0, 13, 1):
        side.set_reference_point('jj' + str(theta), lat + 1.8 * sin(theta * pi / 6), lon + 1.8 * cos(theta * pi / 6))
        side.set_reference_point('ju' + str(theta), lat + 0.6 + 1.8 * sin(theta * pi / 6),
                                 lon + 0.3 + 1.8 * cos(theta * pi / 6))
        side.set_reference_point('jd' + str(theta), lat - 0.6 + 1.8 * sin(theta * pi / 6),
                                 lon + 0.3 + 1.8 * cos(theta * pi / 6))

def check_antiship_success(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    contacts = side.contacts
    strike_agent = get_antiship_aircrafts(side_name, scenario)
    if not {k: v for k, v in contacts.items() if ('DDG' in v.strName)}:
        # print('反舰任务完成，任务飞机剩余%s'%len(strike_agent))
        return True
    else:
        return False

def antiship_to_patrol(side_name, scenario):
    F35 = get_antiship_aircrafts(side_name, scenario)
    side = scenario.get_side_by_name(side_name)
    airs_F35 = side.aircrafts
    contacts = side.contacts
    airs_c56 = {k: v for k, v in airs_F35.items() if 5 <= int(re.sub('\D', '', v.strName)) <= 6}
    airs_c78 = {k: v for k, v in airs_F35.items() if 7 <= int(re.sub('\D', '', v.strName)) <= 8}
    airs_xl = {k: airs_F35[k] for k, v in airs_F35.items() if v.strName in lst}
    air_use = {}
    contacts_F35 = {}
    for k in airs_xl:
        if int(airs_xl[k].strFinishPrepareTime) == 0:
            air_use[k] = airs_xl[k]
    for k in contacts:
        if contacts[k].m_ContactType == 0:
            contacts_F35[k] = contacts[k]
    if len(air_use) < 4 and len(contacts_F35) > 6 and check_DDG(side_name, scenario):
        for k in F35:
            if int(re.sub('\D', '', F35[k].strName)) < 0:  # 分配1/4进入巡逻
                F35[k].cancel_assign_unitlist_to_mission()
                F35[k].assign_unitlist_to_mission('defensive_xl3')


    elif (get_current_time(scenario) >= AttackTime2) and (
            get_current_time(scenario) < AttackTime2 + etc.DURATION_INTERVAL):
        for k in airs_c56:
            if airs_c56[k].get_status_type() == 'validToFly':
                airs_c56[k].cancel_assign_unitlist_to_mission()
                airs_c56[k].assign_unitlist_to_mission('strike1')
    elif get_current_time(scenario) > AttackTime3:
        for k in airs_c78:
            if airs_c78[k].get_status_type() == 'validToFly':
                airs_c78[k].cancel_assign_unitlist_to_mission()
                airs_c78[k].assign_unitlist_to_mission('strike1')
    return False


def get_antiship_aircrafts(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    airs = side.aircrafts
    strike = side.get_strike_missions()
    list_strike = []
    for k in strike:
        list_strike.append(strike[k].strGuid)
    # 获取反舰任务飞机
    airs_antiship = {}
    for k in airs:
        if len(list_strike) != 0:
            if str(airs[k].m_AssignedMission) == list_strike[0]:
                airs_antiship[k] = airs[k]
    return airs_antiship

def antiship_condition_check(side_name, scenario):
    number = num_opaircraft(side_name, scenario)
    print('敌方剩余战机数:', number)
    t = get_current_time(scenario)
    if number <= 6 or t > T:
        return True
    else:
        return False


def num_opaircraft(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    side.static_update()
    airs = side.aircrafts
    score = side.get_score()
    b = len(airs)
    print('我方剩余飞机:', b)
    if score % 139 == 0:
        return int(b - score / 139)
    elif (score + 1843) % 139 == 0:
        return int(b - (score + 1843) / 139)
    else:
        return int(b - (score - 1843) / 139)


def create_support_mission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    ships = side.ships
    if len(side.supportmssns) == 0:
        # 获取支援点、任务单元
        for k in ships:
            # lat: 纬度， lon：经度
            if '驱逐舰' in ships[k].strName:
                lat1, lon1 = ships[k].dLatitude, ships[k].dLongitude
                ship1 = ships[k]

            if '航空母舰' in ships[k].strName:
                lat2, lon2 = ships[k].dLatitude, ships[k].dLongitude
                ship2 = ships[k]
        if side_name == '红方':
            rp = side.add_reference_point('rp', lat1, 155.8)  # 向前开
        else:
            rp = side.add_reference_point('rp', lat1, 157.0000)  # 向前开
        side.add_mission_support('support', [rp])
    support = side.supportmssns

    for i in support:
        cmd = "ScenEdit_SetMission('%s','%s', {%s = '%s'}) " % (
            support[i].m_Side, support[i].strGuid, 'transitThrottleship',
            Throttle(5).name)
        scenario.mozi_server.send_and_recv(cmd)
        scenario.mozi_server.send_and_recv("ScenEdit_SetEMCON('Mission', 'support', 'OECM=Active')")
        scenario.mozi_server.send_and_recv("ScenEdit_SetEMCON('Mission', 'support', 'Sonar=Active')")
        scenario.mozi_server.send_and_recv("ScenEdit_SetEMCON('Mission', 'support', 'oneThirdRule=false')")
        support[i].switch_radar(True)
    for k in ships:
        ships[k].assign_unitlist_to_mission('support')
        ships[k].set_oecm_shutdown('true')
    return True


def contact_analysis(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    contact_dict = side.contacts
    airs = side.aircrafts
    mission_name = []
    for k in airs:
        if airs[k].get_assigned_mission() != None:
            mission_name.append(airs[k].get_assigned_mission().strName)
    if side.get_score() == 1843 + len(airs) * 139:
        for k in airs:
            airs[k].return_to_base()
    air_contact_dict = {}
    missile = {}
    for k, v in contact_dict.items():
        if '不明空中目标' in v.strName or 'F-35' in v.strName:
            air_contact_dict[k] = v
        if '导弹#' in v.strName:
            missile[k] = v
    attacker = 0
    sum_dLongitude = 0
    mean_dLongitude = 9999
    for k in air_contact_dict:
        sum_dLongitude += air_contact_dict[k].dLongitude
        if air_contact_dict[k].dLongitude < 156.8:
            attacker += 1
            history_attacker = attacker
    if len(air_contact_dict) != 0:
        mean_dLongitude = sum_dLongitude / len(air_contact_dict)
    if get_current_time(scenario) < 110 * 60:  # 防守
        if 'attacker_xl1' in mission_name:
            cancel_mission(side_name, scenario)
            reassignment_Amission(side_name, scenario)
        return False

    elif attacker > 0:
        if 'attacker_xl1' in mission_name:
            cancel_mission(side_name, scenario)
            reassignment_Amission(side_name, scenario)
        return False
    else:
        if 'defensive_xl1' in mission_name:
            if mission_exist(side_name, scenario):
                cancel_mission(side_name, scenario)
                reassignment_Dmission(side_name, scenario)

        return True


def cancel_mission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    airs_dic = side.aircrafts
    airs = {k: v for k, v in airs_dic.items() if int(re.sub('\D', '', v.strName)) >= 9}
    ships = side.ships
    for k in airs:
        airs[k].cancel_assign_unitlist_to_mission()
    return False


def reassignment_Amission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    airs_dic = side.aircrafts
    airs = {k: v for k, v in airs_dic.items() if 9 <= int(re.sub('\D', '', v.strName)) <= 10}
    airs1 = {k: v for k, v in airs_dic.items() if 11 <= int(re.sub('\D', '', v.strName)) <= 13}
    airs2 = {k: v for k, v in airs_dic.items() if 14 <= int(re.sub('\D', '', v.strName)) <= 16}
    for k in airs:
        airs[k].assign_unitlist_to_mission('defensive_xl3')
    for k in airs1:
        airs1[k].assign_unitlist_to_mission('defensive_xl1')
    for k in airs2:
        airs2[k].assign_unitlist_to_mission('defensive_xl2')


def reassignment_Dmission(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    airs_dic = side.aircrafts
    airs = {k: v for k, v in airs_dic.items() if 9 <= int(re.sub('\D', '', v.strName)) <= 10}
    airs1 = {k: v for k, v in airs_dic.items() if 11 <= int(re.sub('\D', '', v.strName)) <= 13}
    airs2 = {k: v for k, v in airs_dic.items() if 14 <= int(re.sub('\D', '', v.strName)) <= 16}
    for k in airs:
        airs[k].assign_unitlist_to_mission('attacker_xl1')
    for k in airs1:
        airs1[k].assign_unitlist_to_mission('attacker_xl2')
    for k in airs2:
        airs2[k].assign_unitlist_to_mission('attacker_xl3')


def mission_exist(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    patrol = side.get_patrol_missions()
    if patrol == None:
        return False

    for k in patrol:
        if 'attacker' in patrol[k].strName:
            return True
        else:
            return False

def latlon_to_distant(lat1, lon1, lat2, lon2):
    r = 6371
    c = math.sin(math.radians(lat1)) * math.sin(math.radians(lat2))
    c += math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.cos(math.radians(lon1 - lon2))
    distant = r * math.acos(c)
    return distant


def distant_to_vlat(distant):
    r = 6371
    vlat = distant / r * 180 / math.pi
    return vlat

def distant_to_vlon(distant):
    r = 6371 * math.cos(math.radians(25))
    vlon = distant / r * 180 / math.pi
    return vlon

def create_defensive_patrol_zone(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    ships = side.ships
    contacts = side.contacts
    point_list = []
    if side_name == '红方':
        for k, v in ships.items():
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                r = 55.6  # 驱逐舰防空半径
                d = r / math.sqrt(2)
                # 驱逐舰上方巡逻区
                ap1 = side.add_reference_point('ap1', lat + distant_to_vlat(d), lon + distant_to_vlon(d))
                ap2 = side.add_reference_point('ap2', lat + distant_to_vlat(d), lon - distant_to_vlon(d))
                ap3 = side.add_reference_point('ap3', lat - distant_to_vlat(d), lon - distant_to_vlon(d))
                ap4 = side.add_reference_point('ap4', lat - distant_to_vlat(d), lon + distant_to_vlon(d))
                point_list.append([ap1, ap2, ap3, ap4])
    else:
        for k, v in ships.items():
            if '驱逐舰' in v.strName:
                lat, lon = v.dLatitude, v.dLongitude
                r = 55.6  # 驱逐舰防空半径
                d = r / math.sqrt(2)
                # 驱逐舰上方巡逻区
                ap1 = side.add_reference_point('ap1', lat + distant_to_vlat(d), lon - distant_to_vlon(d))
                ap2 = side.add_reference_point('ap2', lat + distant_to_vlat(d), lon + distant_to_vlon(d))
                ap3 = side.add_reference_point('ap3', lat - distant_to_vlat(d), lon + distant_to_vlon(d))
                ap4 = side.add_reference_point('ap4', lat - distant_to_vlat(d), lon - distant_to_vlon(d))
                point_list.append([ap1, ap2, ap3, ap4])
    # 警戒区
    for theta in range(0, 13, 1):
        side.add_reference_point('ap' + str(theta + 5), lat + 1.8 * sin(theta * pi / 6),
                                 lon + 1.8 * cos(theta * pi / 6))
    # 进攻型巡逻区
    groups = []
    groups1 = []
    if side_name == '红方':
        lat1, lon1 = 25.5014, 157.3024
        latN, lonN = lat1 + distant_to_vlat(2 * r), lon1 - distant_to_vlon(3 * r)
        latS, lonS = lat1 - distant_to_vlat(2 * r), lon1 - distant_to_vlon(3 * r)
    else:
        for contact in contacts.values():
            if '驱逐舰' in contact.strName:
                lat1, lon1 = contact.dLatitude, contact.dLongitude
        # lat1, lon1 = 25.4755, 155.1853
        latN, lonN = lat1 + distant_to_vlat(2 * r), lon1 + distant_to_vlon(3 * r)
        latS, lonS = lat1 - distant_to_vlat(2 * r), lon1 + distant_to_vlon(3 * r)
    z = 0.6
    for theta in range(0, 4, 1):
        groups.append(side.add_reference_point('apn' + str(theta), latN + z * sin(theta * pi / 2),
                                               lonN + z * cos(theta * pi / 2)))
    point_list.append(groups)
    for theta in range(0, 4, 1):
        groups1.append(side.add_reference_point('aps' + str(theta), latS + z * sin(theta * pi / 2),
                                                lonS + z * cos(theta * pi / 2)))
    point_list.append(groups1)
    # 警戒区
    for theta in range(0, 13, 1):
        side.add_reference_point('japn' + str(theta), latN + 1.8 * sin(theta * pi / 6),
                                 lonN + 1.8 * cos(theta * pi / 6))
    for theta in range(0, 13, 1):
        side.add_reference_point('japs' + str(theta), latS + 1.8 * sin(theta * pi / 6),
                                 lonS + 1.8 * cos(theta * pi / 6))
    return point_list


def update_defensive_patrol_zone(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    ships = side.ships
    contacts = side.contacts
    point_list = []
    for k, v in ships.items():
        if '驱逐舰' in v.strName:
            lat, lon = v.dLatitude, v.dLongitude
            r = 55.6  # 驱逐舰防空半径
            d = r / math.sqrt(2)
            # 驱逐舰上方巡逻区
            ap1 = side.set_reference_point('ap1', lat + distant_to_vlat(d), lon + distant_to_vlon(d))
            ap2 = side.set_reference_point('ap2', lat + distant_to_vlat(d), lon - distant_to_vlon(d))
            ap3 = side.set_reference_point('ap3', lat - distant_to_vlat(d), lon - distant_to_vlon(d))
            ap4 = side.set_reference_point('ap4', lat - distant_to_vlat(d), lon + distant_to_vlon(d))
            point_list.append([ap1, ap2, ap3, ap4])
    # 警戒区
    for theta in range(0, 13, 1):
        side.set_reference_point('ap' + str(theta + 5), lat + 1.8 * sin(theta * pi / 6),
                                 lon + 1.8 * cos(theta * pi / 6))

    if side_name == '红方':
        # for contact in contacts.values():
        #     if '驱逐舰' in contact.strName:
        #         lat1, lon1 = contact.dLatitude, contact.dLongitude
        lat1, lon1 = 25.5014, 157.3024
        latN, lonN = lat1 + distant_to_vlat(2 * r), lon1 - distant_to_vlon(3 * r)
        latS, lonS = lat1 - distant_to_vlat(2 * r), lon1 - distant_to_vlon(3 * r)
    else:
        for contact in contacts.values():
            if '驱逐舰' in contact.strName:
                lat1, lon1 = contact.dLatitude, contact.dLongitude
        # lat1, lon1 = 25.4755, 155.1853
        latN, lonN = lat1 + distant_to_vlat(2 * r), lon1 + distant_to_vlon(3 * r)
        latS, lonS = lat1 - distant_to_vlat(2 * r), lon1 + distant_to_vlon(3 * r)
    z = 0.6
    for theta in range(0, 4, 1):
        side.set_reference_point('apn' + str(theta), latN + z * sin(theta * pi / 2),
                                 lonN + z * cos(theta * pi / 2))
    for theta in range(0, 4, 1):
        side.set_reference_point('aps' + str(theta), latS + z * sin(theta * pi / 2),
                                 lonS + z * cos(theta * pi / 2))
    # 警戒区
    for theta in range(0, 13, 1):
        side.set_reference_point('japn' + str(theta), latN + 1.8 * sin(theta * pi / 6),
                                 lonN + 1.8 * cos(theta * pi / 6))
    for theta in range(0, 13, 1):
        side.set_reference_point('japs' + str(theta), latS + 1.8 * sin(theta * pi / 6),
                                 lonS + 1.8 * cos(theta * pi / 6))


def create_defensive_patrol(side_name, scenario):
    side = scenario.get_side_by_name(side_name)
    airs_dic = side.aircrafts
    patrol_missions_dic = side.get_patrol_missions()
    if len(patrol_missions_dic) != 0:
        for k in patrol_missions_dic:
            if 'attacker_xl' in patrol_missions_dic[k].strName:
                return False
    # 根据驱逐舰的坐标，确定巡逻区参考点，根据巡逻区参考点，创建巡逻区
    point_list = create_defensive_patrol_zone(side_name, scenario)
    i = 1
    for point in point_list:
        point_str = []
        for name in point:
            point_str.append(name.strName)
        # 新建巡逻区名字
        patrol_name = 'attacker_xl' + str(i)
        side.add_mission_patrol(patrol_name, 0, point_str)
        patrolmssn = CPatrolMission('T+1_mode', scenario.mozi_server, scenario.situation)
        patrolmssn.strName = patrol_name
        patrolmssn.set_one_third_rule(side_name, 'true')

        i += 1
    return False